package com.carey.blog.sync.csdnblog;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.carey.blog.sync.AbstractMetaWeblog;
import com.carey.blog.sync.util.PageReader;

/**
 * CSDN blog.
 * 
 * <p>
 * API address: http://blog.csdn.net/<b>userId</b>/services/metablogapi.aspx
 * </p>
 * 
 */
public final class CSDNBlog extends AbstractMetaWeblog {

	/**
	 * Logger.
	 */
	private static final Logger LOGGER = Logger.getLogger(CSDNBlog.class
			.getName());

	@Override
	public String getApiAddress() {
		return "http://blog.csdn.net/" + getUserName()
				+ "/services/metablogapi.aspx";
	}

	@Override
	public String getBloggingServiceProvider() {
		return "CSDN Blog";
	}

	@Override
	public List<String> getArchiveDates() {
		final List<String> ret = new ArrayList<String>();

		final String pageContent = PageReader.getContent(getIndexPageURL());
		final String patternString = "<a href=\"/" + getUserName()
				+ "/archive/\\d{4}/\\d{2}\\.aspx";
		final Pattern pattern = Pattern.compile(patternString);
		final Matcher matcher = pattern.matcher(pageContent);

		final List<String> matches = new ArrayList<String>();
		while (matcher.find()) {
			final String match = matcher.group();
			matches.add(match);
		}

		final int yearLength = 4;
		final int monthLength = 2;
		for (final String match : matches) {
			final int idx1 = match.lastIndexOf("/"); // yyyy^/MM.aspx
			final int idx2 = idx1 - yearLength; // ^yyyy/MM
			final int idx3 = idx1 + 1; // yyyy/^MM
			final String year = match.substring(idx2, idx1);
			final String month = match.substring(idx3, idx3 + monthLength);

			ret.add(year + "/" + month);
		}

		return ret;
	}

	/**
	 * Gets the oldest archive date.
	 * 
	 * @return the oldest archive date(yyyy/MM), returns {@code null} if occurs
	 *         error or not found
	 */
	public String getOldestArchiveDate() {
		final String pageContent = PageReader.getContent(getIndexPageURL());
		final String patternString = "<a href=\"/" + getUserName()
				+ "/archive/\\d{4}/\\d{2}\\.aspx";
		final Pattern pattern = Pattern.compile(patternString);
		final Matcher matcher = pattern.matcher(pageContent);

		final List<String> matches = new ArrayList<String>();
		while (matcher.find()) {
			final String match = matcher.group();
			matches.add(match);
		}

		if (0 == matches.size()) {
			return null;
		}

		final String match = matches.get(matches.size() - 1);
		final int yearLength = 4;
		final int monthLength = 2;

		final int idx1 = match.lastIndexOf("/"); // yyyy^/MM.aspx
		final int idx2 = idx1 - yearLength; // ^yyyy/MM
		final int idx3 = idx1 + 1; // yyyy/^MM
		final String year = match.substring(idx2, idx1);
		final String month = match.substring(idx3, idx3 + monthLength);

		return year + "/" + month;
	}

	@Override
	public List<String> getArticleIdsByArchiveDate(final String archiveDate) {
		final URL archivePageURL = getArchivePageURL(archiveDate);
		final String pageContent = PageReader.getContent(archivePageURL);
		final String patternString = "<code><a href=\"/" + getUserName()
				+ "/archive/" + archiveDate + "/\\d\\d/\\d+\\.aspx";
		final Pattern pattern = Pattern.compile(patternString);
		final Matcher matcher = pattern.matcher(pageContent);

		final List<String> ret = new ArrayList<String>();
		while (matcher.find()) {
			final String match = matcher.group();
			final int idx1 = match.lastIndexOf("/") + 1;
			final int idx2 = match.lastIndexOf(".");
			final String id = match.substring(idx1, idx2);

			ret.add(id);
		}

		return ret;
	}

	@Override
	public URL getArchivePageURL(final String archiveDate) {
		try {
			return new URL("http://blog.csdn.net/" + getUserName()
					+ "/archive/" + archiveDate + ".aspx");
		} catch (final MalformedURLException e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);
			return null;
		}
	}

	@Override
	public URL getIndexPageURL() {
		try {
			return new URL("http://blog.csdn.net/" + getUserName());
		} catch (final MalformedURLException e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);
			return null;
		}
	}
}
